/*
*
==============================================================================
*  Name        : 
*  Part of     : Omen Game Engine
*  Description : 
*  Version     : 1.0
*
*  Copyright (c) 2013 Lauri Kortevaara.
* 
==============================================================================
*/

#ifndef OMEN_PLUGIN_H
#define OMEN_PLUGIN_H

#include "OmenConfig.h"
#include "OmenSharedLibrary.h"
#include "IOmenKernel.h"


#include <string>

namespace Omen {

  /// Representation of a plugin
  class Plugin : public Omen::IPlugin 
  {
    /// <summary>Signature for the version query function</summary>
    private: typedef int GetEngineVersionFunction();
    /// <summary>Signature for the plugin's registration function</summary>
    private: typedef void RegisterPluginFunction( Omen::IKernel* kernel);

    /// <summary>Initializes and loads a plugin</summary>
    /// <param name="filename">Filename of the plugin to load</summary>
    public: OMEN_API Plugin(const std::wstring &filename);
    /// <summary>Copies an existing plugin instance</summary>
    public: OMEN_API Plugin(const Plugin &other);
    /// <summary>Unloads the plugin</summary>
    public: OMEN_API ~Plugin();

    /// <summary>Queries the plugin for its expected engine version</summary>
    public: OMEN_API int getEngineVersion() const {
      return getEngineVersionAddress();
    }

    /// <summary>Register the plugin to a kernel</summary>
    /// <param name="kernel">Kernel the plugin should register to</param>
    public: OMEN_API void registerPlugin( Omen::IKernel* kernel);

    /// <summary>Creates a copy of the plugin instance</summary>
    public: Plugin &operator =(const Plugin &other);

    /// <summary>Handle of the loaded shared library</summary>
    private: SharedLibrary::HandleType sharedLibraryHandle;
    /// <summary>Number of references that exist to the shared library</summary>
    private: size_t *referenceCount;
    /// <summary>Function to query for the expected engine version</summary>
    private: GetEngineVersionFunction *getEngineVersionAddress;
    /// <summary>Registers the plugin with the kernel</summary>
    private: RegisterPluginFunction *registerPluginAddress;

  };

  // ----------------------------------------------------------------------- //

} // namespace Omen

#endif // OMEN_PLUGIN_H
